#ifndef __CHAOSPROFILENODE_HPP
#define	__CHAOSPROFILENODE_HPP

/***************************************************************************************************
** This code refrence from :
** Real-Time Hierarchical Profiling for Game Programming Gems 3
**
** by Greg Hjelstrom & Byon Garrabrant
***************************************************************************************************/

#include "ChaosGlobalDefine.hpp"
#include <windows.h>
namespace Chaos
{
	inline void profileGetTicks(const _int64 * ticks)
	{
		__asm
		{
			push edx;
			push ecx;
			mov ecx,ticks;
			_emit 0Fh
			_emit 31h
			mov [ecx],eax;
			mov [ecx+4],edx;
			pop ecx;
			pop edx;
		}
	}

	inline float profileGetTickRate(void)
	{
		static float _CPUFrequency = -1.0f;
		
		if (_CPUFrequency == -1.0f) {
			__int64 curr_rate = 0;
			::QueryPerformanceFrequency ((LARGE_INTEGER *)&curr_rate);
			_CPUFrequency = (float)curr_rate;
		} 
		
		return _CPUFrequency;
	}


	class CHAOS_API ChsProfileNode
	{
	protected:
		const TCHAR *					m_szName;

		int								m_nTotalCalls;
		float							m_fTotalTime;
		int								m_nLastTotalCalls;
		float							m_fLastTotalTime;

		__int64							m_n64StartTime;
		int								m_nRecursionCounter;

		ChsProfileNode *				m_pParent;
		ChsProfileNode *				m_pChild;
		ChsProfileNode *				m_pSibling;

	public:
										ChsProfileNode( const TCHAR * name, ChsProfileNode * parent );
										~ChsProfileNode( void );

		ChsProfileNode*					GetSubNode( const TCHAR * name );

		ChsProfileNode*					GetParent( void );
		ChsProfileNode*					GetSibling( void );
		ChsProfileNode*					GetChild( void );

		void							Reset( void );
		void							Call( void );
		bool							Return( void );

		const TCHAR *					GetName( void )const;
		int								GetTotalCalls( void )const;
		float							GetTotalTime( void )const;
		int								GetLastTotalCalls( void )const;
		float							GetLastTotalTime( void )const;

	};

	inline ChsProfileNode* ChsProfileNode::GetParent( void )
	{
		return m_pParent;
	}

	inline ChsProfileNode* ChsProfileNode::GetSibling( void )
	{
		return m_pSibling;
	}

	inline ChsProfileNode* ChsProfileNode::GetChild( void )
	{
		return m_pChild;
	}

	inline const TCHAR * ChsProfileNode::GetName( void )const
	{
		return m_szName;
	}

	inline int ChsProfileNode::GetTotalCalls( void )const
	{
		return m_nTotalCalls;
	}

	inline float ChsProfileNode::GetTotalTime( void )const
	{
		return m_fTotalTime;
	}

	inline int ChsProfileNode::GetLastTotalCalls( void )const
	{
		return m_nLastTotalCalls;
	}

	inline float ChsProfileNode::GetLastTotalTime( void )const
	{
		return m_fLastTotalTime;
	}

}


#endif //__CHAOSPROFILENODE_HPP
